/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package pl.droidsonroids.gif.gifsample.slice;

import pl.droidsonroids.gif.gifsample.LogUtil;
import pl.droidsonroids.gif.gifsample.ResourceTable;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.ability.DataAbilityHelper;
import ohos.aafwk.ability.DataAbilityRemoteException;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.LayoutScatter;
import ohos.global.resource.RawFileDescriptor;
import ohos.global.resource.RawFileEntry;
import ohos.global.resource.Resource;
import ohos.utils.net.Uri;
import pl.droidsonroids.gif.GifDrawable;
import pl.droidsonroids.gif.GifImageView;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;

/**
 * GifElementSlice
 */
public class GifElementSlice extends AbilitySlice {
    private static final String TAG = GifElementSlice.class.getName();
    ComponentContainer rootLayout;
    GifImageView gifRawFd;
    GifImageView gifUri;
    GifImageView gifFd;
    GifImageView gifByteArray;
    GifImageView gifByteBuffer;
    GifImageView gifInputStream;
    GifImageView gifFromFile;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        initLayoutComponents();
    }

    @Override
    public void onActive() {
        super.onActive();
        initView();
    }

    private void initLayoutComponents() {
        rootLayout = (ComponentContainer) LayoutScatter.getInstance(this)
                .parse(ResourceTable.Layout_ability_gif, null, false);
        gifRawFd = (GifImageView) rootLayout.findComponentById(ResourceTable.Id_GifRawFD);
        gifUri = (GifImageView) rootLayout.findComponentById(ResourceTable.Id_GifUri);
        gifFd = (GifImageView) rootLayout.findComponentById(ResourceTable.Id_GifFD);
        gifByteArray = (GifImageView) rootLayout.findComponentById(ResourceTable.Id_GifByteArray);
        gifByteBuffer = (GifImageView) rootLayout.findComponentById(ResourceTable.Id_GifByteBuffer);
        gifInputStream = (GifImageView) rootLayout.findComponentById(ResourceTable.Id_GifInputStream);
        gifFromFile = (GifImageView) rootLayout.findComponentById(ResourceTable.Id_GifFile);
        super.setUIContent(rootLayout);
    }

    private void initView() {
        GifDrawable gifDrawable = null;
        final byte[] mbyteArray;
        final byte[] mbyteArr;
        InputStream resource;
        BufferedInputStream bufferedInputStream;
        InputStream output;
        try {
            RawFileDescriptor rawFileDescriptor = getResourceManager()
                    .getRawFileEntry("entry/resources/rawfile/anim_flag_iceland.gif").openRawFileDescriptor();

            gifDrawable = new GifDrawable(rawFileDescriptor); // using assetfiledescriptor
            setGifDrawable(gifDrawable, gifRawFd);

            mbyteArray = getByteArrayFromRawFile("entry/resources/rawfile/anim_flag_chile.gif");
            gifDrawable = new GifDrawable(mbyteArray); // using byte Array
            setGifDrawable(gifDrawable, gifByteArray);

            mbyteArr = getByteArrayFromRawFile("entry/resources/rawfile/anim_flag_hungary.gif");
            ByteBuffer mByteBuffer = ByteBuffer.allocateDirect(mbyteArr.length);
            mByteBuffer.put(mbyteArr);
            gifDrawable = new GifDrawable(mByteBuffer); // using ByteBuffer Construction
            setGifDrawable(gifDrawable, gifByteBuffer);

            File gifFile = getFileFromRawFile("entry/resources/rawfile/anim_flag_chile.gif", "chile.gif");
            Uri uri = Uri.parse("file:///" + gifFile.getCanonicalPath()); // checkstyle modification throws error
            gifDrawable = new GifDrawable(DataAbilityHelper.creator(this, uri), uri); // using uri
            setGifDrawable(gifDrawable, gifUri);

            RawFileEntry rawFileEntry = getResourceManager()
                    .getRawFileEntry("entry/resources/rawfile/anim_flag_iceland.gif");
            resource = rawFileEntry.openRawFile();
            bufferedInputStream = new BufferedInputStream(resource);
            gifDrawable = new GifDrawable(bufferedInputStream);
            setGifDrawable(gifDrawable, gifInputStream);

            File file = getFileFromRawFile("entry/resources/rawfile/anim_flag_hungary.gif", "hungary.gif");
            gifDrawable = new GifDrawable(file);
            setGifDrawable(gifDrawable, gifFromFile);

            File fileRandom = getFileFromRawFile("entry/resources/rawfile/anim_flag_england.gif", "england.gif");
            FileDescriptor fd = new RandomAccessFile(fileRandom, "r").getFD();
            if (fd != null) {
                gifDrawable = new GifDrawable(fd);
            }
            setGifDrawable(gifDrawable, gifFd);
        } catch (IOException e) {
            LogUtil.error(TAG, "initView Exception" + e.toString());
        } catch (DataAbilityRemoteException e) {
            LogUtil.error(TAG, "initView DataAbilityRemoteException" + e.toString());
        }
    }

    private void setGifDrawable(GifDrawable gifDrawable, GifImageView gif) {
        if (gifDrawable != null) {
            gif.setImageElement(gifDrawable);
            gifDrawable.setLoopCount(0);
            gifDrawable.getAnimator().start();

            GifDrawable finalGifDrawable = gifDrawable;
            gif.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    finalGifDrawable.getAnimator().stop();
                }
            });
        }
    }

    private File getFileFromRawFile(String string, String filename) {
        byte[] buf = null;
        try {
            File file = new File(getCacheDir(), filename);
            RawFileEntry rawFileEntry = getResourceManager().getRawFileEntry(string);
            Resource resource = rawFileEntry.openRawFile();
            buf = new byte[(int) rawFileEntry.openRawFileDescriptor().getFileSize()];
            int bytesRead = resource.read(buf);
            if (bytesRead != buf.length) {
                throw new IOException("Asset read failed");
            }
            FileOutputStream output = new FileOutputStream(file);
            output.write(buf, 0, bytesRead);
            output.close();
            return file;
        } catch (IOException ex) {
            throw new IllegalStateException(ex);
        }
    }

    private byte[] getByteArrayFromRawFile(String string) {
        byte[] buf = null;
        try {
            RawFileEntry rawFileEntry = getResourceManager().getRawFileEntry(string);
            Resource resource = rawFileEntry.openRawFile();
            buf = new byte[(int) rawFileEntry.openRawFileDescriptor().getFileSize()];
            int bytesRead = resource.read(buf);
            if (bytesRead != buf.length) {
                throw new IOException("Asset read failed");
            }
            return buf;
        } catch (IOException e) {
            LogUtil.error(TAG, "getByteArrayFromRawFile exception" + e.toString());
        }
        return buf;
    }
}
